﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using l1cs.server.model;
using l1cs.server.model.Instance;
using l1cs.server.datatables;
using l1cs.server.serverpackets;
using l1cs.server.templates;

namespace l1cs.server
{
    public class WarTimeController
    {
        private static Logger _log = Logger.getLogger( typeof( WarTimeController ).FullName );

        private static WarTimeController _instance;
        private L1Castle[] _l1castle = new L1Castle[8];
        private DateTime[] _war_start_time = new DateTime[8];
        private DateTime[] _war_end_time = new DateTime[8];
        private bool[] _is_now_war = new bool[8];

        private WarTimeController()
        {
            for ( int i = 0; i < _l1castle.Length; i++ )
            {
                _l1castle[i] = CastleTable.getInstance().getCastleTable( i + 1 );
                _war_start_time[i] = _l1castle[i].getWarTime();
                _war_end_time[i] = _l1castle[i].getWarTime();
                switch ( Config.ALT_WAR_TIME_UNIT )
                {
                    case "d":
                        _war_end_time[i].AddDays( Config.ALT_WAR_TIME );
                        break;
                    case "h":
                        _war_end_time[i].AddHours( Config.ALT_WAR_TIME );
                        break;
                    case "m":
                        _war_end_time[i].AddMinutes( Config.ALT_WAR_TIME );
                        break;
                }
            }
        }

        public static WarTimeController getInstance()
        {
            if ( _instance == null )
            {
                _instance = new WarTimeController();
            }
            return _instance;
        }

        public void threadSub( Object state )
        {
            while ( true )
            {
                checkWarTime(); // 戦争時間をチェック
                Thread.Sleep( 1000 );
            }
        }

        public bool isNowWar( int castle_id )
        {
            return _is_now_war[castle_id - 1];
        }

        public void checkCastleWar( L1PcInstance player )
        {
            for ( int i = 0; i < 8; i++ )
            {
                if ( _is_now_war[i] )
                {
                    player.sendPackets(
                            new S_PacketBox( S_PacketBox.MSG_WAR_GOING, i + 1 ) ); // %sの攻城戦が進行中です。
                }
            }
        }

        /// <summary>
        /// 戦争時間をチェックする。
        /// </summary>
        private void checkWarTime()
        {
            for ( int i = 0; i < 8; i++ )
            {
                if ( _war_start_time[i] < DateTime.Now && DateTime.Now < _war_end_time[i] )
                {
                    // 戦争開始
                    if ( _is_now_war[i] == false )
                    {
                        _is_now_war[i] = true;
                        // 旗をspawnする
                        L1WarSpawn warspawn = new L1WarSpawn();
                        warspawn.SpawnFlag( i + 1 );
                        // 城門を修理して閉じる
                        foreach ( L1DoorInstance door in DoorSpawnTable.getInstance().getDoorList() )
                        {
                            if ( L1CastleLocation.checkInWarArea( i + 1, door ) )
                            {
                                door.repairGate();
                            }
                        }

                        // %sの攻城戦が始まりました。
                        L1World.getInstance().broadcastPacketToAll(
                                new S_PacketBox( S_PacketBox.MSG_WAR_BEGIN, i + 1 ) );
                        int[] loc = new int[3];
                        foreach ( L1PcInstance pc in L1World.getInstance().getAllPlayers() )
                        {
                            int castleId = i + 1;
                            if ( L1CastleLocation.checkInWarArea( castleId, pc ) && !pc.isGm() )
                            { // 旗内に居る
                                L1Clan clan = L1World.getInstance().getClan( pc.getClanname() );
                                if ( clan != null )
                                {
                                    if ( clan.getCastleId() == castleId )
                                    { // 城主クラン員
                                        continue;
                                    }
                                }
                                loc = L1CastleLocation.getGetBackLoc( castleId );
                                L1Teleport.teleport( pc, loc[0], loc[1], (short)loc[2], 5, true );
                            }
                        }
                    }
                }
                else if ( _war_end_time[i] < DateTime.Now )
                { // 戦争終了
                    if ( _is_now_war[i] == true )
                    {
                        _is_now_war[i] = false;
                        // %sの攻城戦が終了しました。
                        L1World.getInstance().broadcastPacketToAll( 
                                    new S_PacketBox( S_PacketBox.MSG_WAR_END, i + 1 ) ); 
                        switch ( Config.ALT_WAR_INTERVAL_UNIT )
                        {
                            case "d":
                                _war_start_time[i].AddDays( Config.ALT_WAR_INTERVAL );
                                _war_end_time[i].AddDays( Config.ALT_WAR_INTERVAL );
                                break;
                            case "h":
                                _war_start_time[i].AddHours( Config.ALT_WAR_INTERVAL );
                                _war_end_time[i].AddHours( Config.ALT_WAR_INTERVAL );
                                break;
                            case "m":
                                _war_start_time[i].AddMinutes( Config.ALT_WAR_INTERVAL );
                                _war_end_time[i].AddMinutes( Config.ALT_WAR_INTERVAL );
                                break;
                        }
                        _l1castle[i].setTaxRate( 10 ); // 税率10%
                        _l1castle[i].setPublicMoney( 0 ); // 公金クリア
                        CastleTable.getInstance().updateCastle( _l1castle[i] );

                        int castle_id = i + 1;
                        foreach ( L1Object l1object in L1World.getInstance().getObject() )
                        {
                            // 戦争エリア内の旗を消す
                            if ( l1object is L1FieldObjectInstance )
                            {
                                L1FieldObjectInstance flag = (L1FieldObjectInstance)l1object;
                                if ( L1CastleLocation.checkInWarArea( castle_id, flag ) )
                                {
                                    flag.deleteMe();
                                }
                            }
                            // クラウンを消す
                            if ( l1object is L1CrownInstance )
                            {
                                L1CrownInstance crown = (L1CrownInstance)l1object;
                                if ( L1CastleLocation.checkInWarArea( castle_id, crown ) )
                                {
                                    crown.deleteMe();
                                }
                            }
                            // タワーを一旦消す
                            if ( l1object is L1TowerInstance )
                            {
                                L1TowerInstance tower = (L1TowerInstance)l1object;
                                if ( L1CastleLocation.checkInWarArea( castle_id, tower ) )
                                {
                                    tower.deleteMe();
                                }
                            }
                        }
                        // タワーを再出現させる
                        L1WarSpawn warspawn = new L1WarSpawn();
                        warspawn.SpawnTower( castle_id );

                        // 城門を元に戻す
                        foreach ( L1DoorInstance door in DoorSpawnTable.getInstance().getDoorList() )
                        {
                            if ( L1CastleLocation.checkInWarArea( castle_id, door ) )
                            {
                                door.repairGate();
                            }
                        }
                    }
                }
            }
        }
    }
}
